package com.songlanyun.modules.freighttemplate.entity;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.IOException;
import java.math.BigDecimal;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.type.TypeReference;
import com.songlanyun.common.drive.RootEntity;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.custom.ClassConvertUtils;
import com.songlanyun.common.validator.group.AddGroup;
import com.songlanyun.common.validator.group.UpdateGroup;
import com.songlanyun.modules.freighttemplate.values.AreaRule;
import lombok.Data;
import org.apache.commons.lang.StringUtils;

import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;

/**
 * 商家的物流模板的规则表（有一条默认规则，有其它与地区关联的特定规则表）
 * 
 * @author lubo
 * @email sunlightcs@gmail.com
 * @date 2020-11-09 18:03:39
 */
@Data
@TableName("yxt_shop_freight_template_rule")
public class FreightTemplateRule extends RootEntity<Integer,FreightTemplateRule> implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 
	 */
	@TableId
	@NotNull(message = "修改时必须指定Id", groups = {UpdateGroup.class})
	@Null(message = "新增时不能指定Id", groups = {AddGroup.class})
	private Integer id;
	/**
	 * 商家运费模板id
	 */
	private Integer freightTemplateId;

	/**
	 * 运费计算方式(0件，1重,2体积)
	 */
	private OrderConstant.FreightComputeMode freightComputeMode;

	/**
	 * 初始门槛（首件，首重，首体积(运费)）
	 * 首件，首重，首体积
	 */
	@DecimalMin(value = "0.00", message = "初始门槛最小是0",groups = {AddGroup.class,UpdateGroup.class})
	@DecimalMax(value = "99999999.00", message = "初始门槛最大是99999999.00",groups = {AddGroup.class,UpdateGroup.class})
	private BigDecimal startStandards;

	public void formatStartStandards()
	{
		if(OrderConstant.FreightComputeMode.ITEM.equals(this.getFreightComputeMode()))
		{
			this.startStandards = BigDecimal.valueOf(this.startStandards.intValue());
		}
	}
	/**
	 * 初始运费（首件，首重，首体积(运费)）
	 */
	@DecimalMin(value = "0.00", message = "初始运费最小是0",groups = {AddGroup.class,UpdateGroup.class})
	@DecimalMax(value = "99999999.00", message = "初始运费最大是99999999.00",groups = {AddGroup.class,UpdateGroup.class})
	private BigDecimal startFreight;

	/**
	 * 续加多少量
	 */
	@DecimalMin(value = "0.00", message = "续量最小是0",groups = {AddGroup.class,UpdateGroup.class})
	@DecimalMax(value = "99999999.00", message = "续量最大是99999999.00",groups = {AddGroup.class,UpdateGroup.class})
	private BigDecimal continued;
	public void formatContinued()
	{
		if(OrderConstant.FreightComputeMode.ITEM.equals(this.getFreightComputeMode()))
		{
			this.continued = BigDecimal.valueOf(this.continued.intValue());
		}
	}
	/**
	 * 续加的运费
	 */
	@DecimalMin(value = "0.00", message = "续加的运费最小是0",groups = {AddGroup.class,UpdateGroup.class})
	@DecimalMax(value = "99999999.00", message = "续加的运费最大是99999999.00",groups = {AddGroup.class,UpdateGroup.class})
	private BigDecimal continuedFreight;
	/**
	 * 是否默认规则
	 */
	private Boolean general;

	/**
	 * 区域规则字面量
	 * 北京市[全境],天津市[全境],湖北省[武汉市，十堰市]
	 */
	private String areaRuleLiteral;

	/**
	 * 区域规则(数据结构)
	 * {
	 *       "110000":{"all":true,"code":"110000","list":{},"name":"北京市"},
	 *       "120000":{"all":true,"code":"120000","list":{},"name":"天津市"},
	 *       "420000":{"all":false,"code":"420000","name":"湖北省","list":{
	 *       "420100":{"all":true,"code":"420100","name":"武汉市","list":{}},
	 *       "420300":{"all":true,"code":"420300","name":"十堰市","list":{}}}}
	 * }
	 */
	@TableField(exist = false)
	private 	Map<String, AreaRule> areaRule;
	public void setAreaRule(Map<String, AreaRule> areaRule)
	{
		this.areaRule = areaRule;
		if(areaRule==null || areaRule.isEmpty() || areaRule.size()==0)
		{
			this.areaRuleValue = "{}";
			this.areaRuleLiteral = "";
		}
		else
		{
			this.areaRuleValue = JSONUtil.toJsonStr(areaRule);
			this.areaRuleLiteral = this.processLiteral(areaRule);
		}
	}

	/**
	 * 解析成字面量用来做显示
	 * @param list
	 * @return
	 */
	private String processLiteral(Map<String, AreaRule> list) {
		if (list == null || list.size() == 0) return "";

		List<String> collect = list.entrySet().stream().map(o -> {
			if (o.getValue().getAll()) {
				return o.getValue().getName() + "[全境]";
			} else {
				Map<String, AreaRule> child = o.getValue().getList();
				String join = "";
				if (child.size() > 0) {
					List<String> childStr = child.entrySet().stream().map(t -> t.getValue().getName()).distinct().collect(Collectors.toList());
					join = StringUtils.join(childStr, ",");
				}
				return o.getValue().getName() + "[" + join + "]";
			}
		}).collect(Collectors.toList());
		return StringUtils.join(collect, ",");
	}

	/**
	 * 区域规则json值(数据结构)
	 */
	@JsonIgnore
	private  String areaRuleValue;
	public void setAreaRuleValue(String areaRuleValue)
	{
		this.areaRuleValue = areaRuleValue;
		try {
			this.areaRule = ClassConvertUtils.stringToClassSnake(areaRuleValue, new TypeReference<Map<String, AreaRule>>() {
			});
		} catch (IOException e) {
			this.areaRule = new HashMap<>();
		}
	}

	/**
	 * 判断当前规则是否匹配
	 * @param provinceCode
	 * @param cityCode
	 * @return
	 */
	public boolean hasSet(String provinceCode,String cityCode)
	{
		if(StringUtils.isEmpty(provinceCode)) return false;
		boolean hasProvince = this.getAreaRule().containsKey(provinceCode);
		//如果省都没有找到返回假
		if(!hasProvince) {
			return false;
		}
		//如果省是全境，返回真
		if(this.getAreaRule().get(provinceCode).getAll())
		{
			return true;
		}
		//如果城市找到了返回真，否则返回假
		Map<String, AreaRule> list = this.getAreaRule().get(provinceCode).getList();
		return  list.size()>0 && list.containsKey(cityCode);

	}

	@Override
	public Integer getIdentity() {
		return getId();
	}
}
